﻿using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Windows.Admin.Domain;
using Windows.Admin.Infrastructure.EFCore;
using Windows.Admin.Infrastructure.EFCore.Extensions;
using Windows.FileStorage.Contract;
using Windows.Infrastructure.EFCore.Share.Extensions;
using Windows.Infrastructure.Share.CustomException;
using Windows.Service.Share;

namespace Windows.Admin.Service
{
    public class EmployeeService : IEmployeeService
    {
        private readonly IMapper _mapper;
        //private readonly ICache _cache;
        private readonly AdminDbContext _db;
        private readonly Attachment.AttachmentClient _client;
        public EmployeeService(IMapper mapper, AdminDbContext db
            , Attachment.AttachmentClient client
            )
        {
            _mapper = mapper;
            _db = db;
            _client = client;
        }
        /// <summary>
        /// 获取员工列表基础资料
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<List<EmployeeResponse>> GetBasicEmployees(IdsRequest request)
        {
            var query = _db.Employee.AsQueryable();
            if (request.Ids != null && request.Ids.Length > 0)
                query = query.Where(x => request.Ids.Contains(x.Id));
            return _mapper.Map<List<EmployeeResponse>>(await query.ToListAsync());
        }
        /// <summary>
        /// 员工视图
        /// </summary>
        /// <param name="info"></param>
        /// <param name="isEnable"></param>
        /// <returns></returns>
        public async Task<PageResponse<EmployeeResponse>> Query(PageRequest<EmployeeRequest> request)
        {
            var query = Where(request);
            var list = await query.Paging(request.PageIndex, request.PageSize).ToListAsync();
            var response = new PageResponse<EmployeeResponse>
            {
                TotalCount = await query.CountAsync(),
                PageIndex = request.PageIndex,
                PageSize = request.PageSize,
                List = _mapper.Map<List<EmployeeResponse>>(list)
            };
            return response;
        }
        /// <summary>
        /// 获取id的员工详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<EmployeeResponse> Detail(int id)
        {
            var model = await _db.Employee.Include(x => x.User).Include(x => x.Organization_Employees).ThenInclude(x => x.Organization).Include(x => x.Post_Employees).ThenInclude(x => x.Post).FindByIdAsync(id);
            var response = _mapper.Map<EmployeeResponse>(model);
            //AttachmentRequest request = new() 
            //{
            //    OwnerId = model.Id
            //};
            //var attaResponse = await _attachmentGrpcSvc.GetAttachment(request);
            //if(!attaResponse.AttachmentPath.IsNullOrEmpty())
            //    response.AttachmentPath = attaResponse.AttachmentPath;
            return response;
            
        }
        /// <summary>
        /// 员工保存
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        /// <exception cref="ApiException"></exception>
        public async Task Save(EmployeeSaveRequest request)
        {
            if (_db.Employee.Any(x => x.Number.ToLower() == request.Number && x.Id != request.Id))
                throw new ApiException("员工编号已存在!");
            Employee? model = _mapper.Map<Employee>(request);
            if (request.Id != null)
            {
                model = await _db.Employee.Include(x => x.Organization_Employees).Include(x => x.Post_Employees).FindByIdAsync(request.Id.Value);
                if (model == null)
                    throw new ApiException("员工不存在!");
                //model.UserId = request.UserId;
                model.Number = request.Number;
                model.Name = request.Name;
                model.IDCard = request.IDCard;
                model.Gender = request.Gender;
                model.Marriage = request.Marriage;
                model.Education = request.Education;
                model.MobilePhone = request.MobilePhone;
                model.Email = request.Email;
                model.Address = request.Address;
                model.HireDate = request.HireDate;
                model.TermDate = request.TermDate;
                model.Status = request.Status;
                model.Avatar = request.Avatar;
                model.Remark = request.Remark;
                _db.RemoveRange(model.Organization_Employees);
                _db.RemoveRange(model.Post_Employees);
            }
            if (request.OrganizationIds.Length > 0)
            {
                List<Organization_Employee> organization_Employees = new();
                foreach (var organizationId in request.OrganizationIds)
                {
                    Organization_Employee organization_Employee = new()
                    {
                        OrganizationId = organizationId
                    };
                    organization_Employees.Add(organization_Employee);
                }
                model.Organization_Employees = organization_Employees;
            }
            if (request.PostIds.Length > 0)
            {
                List<Post_Employee> post_Employees = new();
                foreach (var postId in request.PostIds)
                {
                    Post_Employee post_Employee = new()
                    {
                        PostId = postId
                    };
                    post_Employees.Add(post_Employee);
                }
                model.Post_Employees = post_Employees;
            }

            if (request.Id == null)
                await _db.AddAsync(model);
            if (request.AttachmentId != null)
            {
                AttachmentRequest attachmentRequest = new()
                {
                    OwnerId = model.Id,
                    AttachmentId = request.AttachmentId.Value,
                };
                await _client.UpdateOwnerAsync(attachmentRequest);
            }
            await _db.SaveChangesAsync();
        }
        /// <summary>
        /// 绑定用户
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        /// <exception cref="ApiException"></exception>
        public async Task BindUser(BindUserRequest request)
        {
            if (await _db.Employee.AnyAsync(x => x.UserId == request.UserId && x.Id != request.Id))
                throw new ApiException("此用户已绑定给其他员工!");

            var model = await _db.Employee.FindByIdAsync(request.Id) ?? throw new ApiException("员工不存在!");
            model.UserId = request.UserId;
            await _db.SaveChangesAsync();
        }
        /// <summary>
        /// 员工删除
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task Remove(IdsRequest request)
        {
            await _db.Employee.RemoveAsync(request.Ids);
            await _db.SaveChangesAsync();
        }
        /// <summary>
        /// 获取聊天界面的员工列表
        /// </summary>
        /// <returns></returns>
        //[Caching]
        public async Task<List<ChatEmployeeResponse>> GetChatEmployees()
        {
            var organizations = await _db.Organization.ToListAsync();
            var oe = await _db.Organization_Employee.Include(x => x.Employee).ThenInclude(x => x!.User).ToListAsync();
            var list = _mapper.Map<List<ChatEmployeeResponse>>(oe);
            list.AddRange(_mapper.Map<List<ChatEmployeeResponse>>(organizations));
            return list;
        }
        /// <summary>
        /// 获取聊天界面的员工详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="ApiException"></exception>
        public async Task<EmployeeResponse> GetChatEmployeeDetail(long id)
        {
            var model = await _db.Employee.FindAsync(id) ?? throw new ApiException("员工不存在!");
            return _mapper.Map<EmployeeResponse>(model);
        }
        /// <summary>
        /// 获取当前Id及下面节点的Id
        /// </summary>
        /// <param name="list"></param>
        /// <param name="ids"></param>
        /// <param name="id"></param>
        /// <param name="isFirst"></param>
        protected void GetCurrentAndChildrenIds(List<Organization> list, List<long> ids, long id, bool isFirst = false)
        {
            if (isFirst)
                ids.Add(id);
            var childrens = list.Where(x => x.PId == id).Select(s => s.Id).ToList();
            if (childrens.Count > 0)
            {
                ids.AddRange(childrens);
                foreach (int cId in childrens)
                {
                    GetCurrentAndChildrenIds(list, ids, cId);
                }
            }
        }
        private IQueryable<Employee> Where(PageRequest<EmployeeRequest> request)
        {
            IQueryable<Employee> query = _db.Employee.Include(x => x.User).Include(x => x.Organization_Employees).ThenInclude(x => x.Organization).Include(x => x.Post_Employees).ThenInclude(x => x.Post);
            if (request.Query.OrganizationId != null)
            {
                query = query.GetByOrganizationId(request.Query.OrganizationId.Value);
            }
            if (request.Query.PostId != null)
            {
                query = query.GetByPostId(request.Query.PostId.Value);
            }
            if (request.Query.Number != null)
            {
                query = query.Where(x => x.Number.Contains(request.Query.Number));
            }
            if (request.Query.IDCard != null)
            {
                query = query.Where(x => x.IDCard.Contains(request.Query.IDCard));
            }
            if (request.Query.Name != null)
            {
                query = query.Where(x => x.Name.Contains(request.Query.Name));
            }
            if (request.Query.Education != null)
            {
                query = query.Where(x => x.Education == request.Query.Education);
            }
            if (request.Query.Status != null)
            {
                query = query.Where(x => x.Status == request.Query.Status);
            }
            if (request.Query.MobilePhone != null)
            {
                query = query.Where(x => x.MobilePhone.Contains(request.Query.MobilePhone));
            }
            if (request.Query.HireDateBegin != null)
            {
                query = query.Where(x => x.HireDate >= request.Query.HireDateBegin);
            }
            if (request.Query.HireDateEnd != null)
            {
                query = query.Where(x => x.HireDate <= request.Query.HireDateEnd);
            }
            if (request.Query.TermDateBegin != null)
            {
                query = query.Where(x => x.TermDate >= request.Query.HireDateBegin);
            }
            if (request.Query.TermDateEnd != null)
            {
                query = query.Where(x => x.TermDate <= request.Query.HireDateEnd);
            }
            return query;
        }
        /// <summary>
        /// 获取当前Id及父节点的Id
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="outList"></param>
        /// <param name="t"></param>
        protected void GetCurrentAndParents(List<Organization> list, List<Organization> outList, Organization t)
        {
            outList.Add(t);
            var parent = list.FirstOrDefault(x => Equals(x.Id, t.PId));
            if (parent != null)
            {
                GetCurrentAndParents(list, outList, parent);
            }
        }
    }
}
